
#include "stdafx.h"

#include "FASTClientApplication.h"
#include "FASTClientMessageInterpreter.h"

#include <Codecs/XMLTemplateParser.h>
#include <Codecs/TemplateRegistry.h>

#include <Communication\Assembler.h>
#include <Codecs/StreamingAssembler.h>
#include <Codecs/MessagePerPacketAssembler.h>

#include <Codecs/GenericMessageBuilder.h>
#include <Communication\TCPReceiver.h>

#include <Codecs\DataDestination.h>
#include <Codecs\FieldInstruction.h>

#include <iostream>

using namespace QuickFAST;

///////////////////////
// ClientApplication

FASTClientApplication::FASTClientApplication()
	: fastEncodedHeaderAnalizer_(0, 0, true /* has block size */)
{
}

FASTClientApplication::~FASTClientApplication()
{
}


int FASTClientApplication::run()
{
	int result = 0;

	try
	{
      //////////////////////////////////////
      // Create an application object to use
      // the incoming data.  In this case to
      // accept complete messages and interpret
      // them to standard out.
      FASTClientMessageInterpreter handler(std::cout);
      // and use the interpreter as the consumer
      // of generic messages.
      Codecs::GenericMessageBuilder builder(handler);
	  builder.setVerbose(&std::cout);

      ///////////////////////////////////////////////////////////////////////////////
      // Create an object to receive data from a tcp connection
      Communication::TCPReceiver receiver(GetIP(), GetPort());

	  Communication::AssemblerPtr pAssembler = CreateAssemblerForMode(builder);

      /////////////////////////////////////////////
      // do final initialzation of the data receiver.
      receiver.start(*pAssembler);

	  Codecs::DataDestination destination;
	  WorkingBuffer tempBuffer;
	  Codecs::FieldInstruction::encodeUnsignedInteger(destination, tempBuffer, 123 /* just dummy value */);


	  size_t sentBytes = receiver.send(destination);

      /////////////////////////////////////
      // run the event loop in this thread.
      // Do not return until receiver stops.
      // The RawFileReceiver will stop at end of file.
      receiver.run();
  }
  catch (std::exception & e)
  {
    std::cerr << "FASTClientApplication::run(): Exception:" << e.what() << std::endl;
    result = -1;
  }

  return result;
}

Communication::AssemblerPtr FASTClientApplication::CreateAssemblerForMode(Messages::ValueMessageBuilder & builder)
{
	Communication::AssemblerPtr result;	

	if(GetMode() == "1")
	{
		std::cout << "CreateAssemblerForMode: mode 1 - Testing StreamingAssembler with more then one message per block" << std::endl;
		result = Communication::AssemblerPtr(new Codecs::StreamingAssembler(GetRegistry(), fastEncodedHeaderAnalizer_, builder));
	}
	else if (GetMode() == "2")
	{
		std::cout << "CreateAssemblerForMode: mode 2 - Testing MessagePerPacketAssembler with long-long block sending via TCP" << std::endl;
		result = Communication::AssemblerPtr(new Codecs::MessagePerPacketAssembler(GetRegistry(), fastEncodedHeaderAnalizer_, noHeaderAnalizer_, builder));
	}
	else if (GetMode() == "3")
	{
		std::cout << "CreateAssemblerForMode: mode 3 - Testing SpecialAssembler with long-long block sending via TCP" << std::endl;
		std::cerr << "Not implemented yet." << std::endl;
	}
	else
		std::cerr << "CreateAssemblerForMode: Incorrect mode:" << GetMode() << std::endl;

	return result;
}
